
package ogame.utilities;

import java.util.ArrayList;

/**
 *
 * @author scchang
 */
public class Resources {
    protected int metal;
    protected int crystal;
    protected int deut;
    
    public Resources(){
        this(0, 0, 0);
    }
    
    public Resources(int metal, int crystal, int deut){
        this.metal = metal;
        this.crystal = crystal;
        this.deut = deut;
    }
    
    public int getTotal(){
        return this.metal+this.crystal+this.deut;
    }
    
    public double getTotal(double weight_m, double weight_c, double weight_d){
        return this.metal*weight_m + this.crystal*weight_c + this.deut*weight_d;
    }

    /**
     * @return the metal
     */
    public int getMetal() {
        return metal;
    }

    /**
     * @param metal the metal to set
     */
    public void setMetal(int metal) {
        this.metal = metal;
    }

    /**
     * @return the crystal
     */
    public int getCrystal() {
        return crystal;
    }

    /**
     * @param crystal the crystal to set
     */
    public void setCrystal(int crystal) {
        this.crystal = crystal;
    }

    /**
     * @return the deut
     */
    public int getDeut() {
        return deut;
    }

    /**
     * @param deut the deut to set
     */
    public void setDeut(int deut) {
        this.deut = deut;
    }
    
    public String toString(){
        return "Metal: " + this.metal + " Crystal: " + this.crystal 
                + " Deut: " + this.deut;
    }
    
    public static Resources parseResources(byte[] input){
        int currentIndex = 0;
        int[] resources = new int[3];
        for(int i = 0; i < 3; ++i){// Three types of resources
            int numContained = input[currentIndex];
            int amount = 0;
            for(int j = 0; j < numContained; ++j){
                currentIndex++;
                amount = (amount*256) + input[currentIndex] + 128;
            }
            resources[i] = amount;
            currentIndex++;
        }
        return new Resources(resources[0], resources[1], resources[2]);
    }
    
    public byte[] encode(){
        int[] resources = new int[3];
        resources[0] = this.metal;
        resources[1] = this.crystal;
        resources[2] = this.deut;
        
        ArrayList<Byte> theList = new ArrayList<>();
        
        for(int i = 0; i < resources.length; ++i){
            int count = 0;
            if(resources[i] != 0){
                count = (int)Math.floor(Math.log(resources[i])/Math.log(256)) 
                        + 1;
            }else{
                count = 1;
            }
            theList.add(Byte.parseByte(""+count));
            for(int j = count - 1; j >= 0; --j){
                int mod = (int)Math.floor(resources[i]/(Math.pow(256, j)));
                resources[i] -= mod*Math.pow(256, j);
                mod -= 128;
                theList.add(new Byte(""+mod));
            }
        }
        
        Byte[] resultByte = new Byte[theList.size()];
        resultByte = theList.toArray(resultByte);

        byte[] result = new byte[theList.size()];
        for(int i = 0; i < result.length; ++i){
            result[i] = resultByte[i];
        }
        return result;
    }
    
    public static boolean unitTest(){
        
        Resources res = new Resources(0, 128, 256);
        Resources result = Resources.parseResources(res.encode());
        
        if(result.getMetal() != 0){
            System.out.println("Metal is non-zero.");
            return false;
        }

        if(result.getCrystal() != 128){
            System.out.println("Crystal is not 128.");
            return false;
        }
        
        if(result.getDeut() != 256){
            System.out.println("Deut is not 256.");
            return false;
        }
        
        res = new Resources(512, 65536, 0);
        result = Resources.parseResources(res.encode());
        
        if(result.getMetal() != 512){
            System.out.println("Metal is no 512.");
            return false;
        }
        
        if(result.getCrystal() != 65536){
            System.out.println("Cyrsal is not 65536.");
            return false;
        }
        
        if(result.getDeut() != 0){
            System.out.println("Deut is non-zero.");
            return false;
        }
        
        result = Resources.parseResources(new Resources().encode());
        if(result.getMetal() != 0){
            System.out.println("Metal is not 0.");
            return false;
        }else if(result.getCrystal() != 0){
            System.out.println("Crystal is not 0.");
            return false;
        }else if(result.getDeut() != 0){
            System.out.println("Deut is not 0.");
            return false;
        }
        
        return true;
    }
    
}
